package com.vpen.block.queue;

import com.vpen.block.model.PlanDTO;
import org.springframework.stereotype.Component;


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @version: 1.0
 * @author: Vpen
 * @date: 2021/11/21 9:10
 * @content: 共同操作
 */

public class BlockQueuePlanBuff {
    private static final Integer BuffSize = 10;
    private static final Integer ListSize = 5;
    private final BlockingQueue<PlanDTO> plans = new LinkedBlockingQueue<>(BuffSize);
    private final List<PlanDTO> list = new ArrayList<>(ListSize);
    /**
     * 添加到阻塞退列
     *
     * @param plan plan
     * @return void
     * @author Vpen
     * @date 2021/11/21 11:11
     * @name save
     **/
    public synchronized void save1(PlanDTO plan) throws InterruptedException {
        // 当阻塞退列超过指定大小，阻塞，应该不需要这一步，本身阻塞队列put也是阻塞的
        if (plans.size() > BuffSize) {
            this.wait();
        }
        plans.put(plan);
        System.out.println(Thread.currentThread().getName() + ":生产了一条消息，队列数量：" + plans.size());
        this.notify();
    }

    /**
     * 消费阻塞队列里
     *
     * @return void
     * @author Vpen
     * @date 2021/11/21 11:00
     * @name get
     **/
    public synchronized void get1() throws InterruptedException {
        if (plans.size() == 0) {
            // 当阻塞队列为空时，阻塞线程,释放同步锁
            this.wait();
        } else {
            // 当阻塞队列的大小超过指定大小，获取里面的元素，插入到数据库
            if (plans.size() > ListSize) {
                for (int i = 0; i < ListSize - 1; i++) {
                    PlanDTO take = plans.take();
                    list.add(take);
                }
                System.out.println(Thread.currentThread().getName() + ":消费了" + list.size() + "条数据,添加到数据库");
                System.out.println(list);
                list.clear();
                System.out.println("当前阻塞队列：" + plans.size());
            }
            //同步代码块运行完 通知其它阻塞的线程去竞争锁
            this.notify();
        }
    }


    /*******************************阻塞队列的阻塞方法put和take********************************/



    /**使用阻塞队列的put阻塞方法
     * @author Vpen
     * @date 2021/11/21 11:15
     * @name save2
     * @param plan plan
     * @return void
     **/
    public synchronized void save2(PlanDTO plan) throws InterruptedException {
        plans.put(plan);
        System.out.println(Thread.currentThread().getName() + ":生产了一条消息，队列数量：" + plans.size());
        this.notify();

    }

    /**使用阻塞队列的take阻塞方法
     * @author Vpen
     * @date 2021/11/21 11:15
     * @name get2
     * @return void
     **/
    public synchronized void get2() throws InterruptedException {
        // 当阻塞队列的大小超过指定大小，获取里面的元素，插入到数据库
        if (plans.size() > ListSize) {
            for (int i = 0; i < ListSize - 1; i++) {
                PlanDTO take = plans.take();
                list.add(take);
            }
            System.out.println(Thread.currentThread().getName() + ":消费了" + list.size() + "条数据,添加到数据库");
            System.out.println(list);
            list.clear();
            System.out.println("当前阻塞队列：" + plans.size());
        }
        //同步代码块运行完 通知其它阻塞的线程去竞争锁
        this.notify();
    }

}
